*(*(tempField)+next) = 0; /* put a 0 terminator on the result */
/* clean up */
DisposHandle(orderHandle);
DisposHandle(lsHandle);
/* return the result */
return tempField;
}
/* XFCN entry point */
pascal void main(paramPtr)
XCmdBlockPtr paramPtr;
{
Str255 paramStr,lineStr,itemStr;
int numItems,i,j;
char c;
/* Prepare to use globals */
RememberA0();
SetUpA4();
/* check parameter count */
if (paramPtr->paramCount != 2) {
strcpy(paramStr,"Not enough parameters in MultiSort.");
ResultIs(paramPtr,paramStr);
RestoreA4();
return;
}
/* get the input container copy */
MoveHHi(paramPtr->params[0]);
HLock(paramPtr->params[0]);
theField = (Handle)paramPtr->params[0];
/* get the specification container */
HLock(paramPtr->params[1]);
strcpy(paramStr,*(paramPtr->params[1]));
/* check bounds on sort items */
numSortFields = NumHCLines(paramStr);
if (numSortFields > maxItems) {
strcpy(paramStr,"MultiSort cannot handle more than 32 sort items.");
ResultIs(paramPtr,paramStr);
RestoreA4();
return;
}
/* check each specification line and remember the specs */
for (i=0;i<numSortFields;i++) {
GetHCLine(i+1,paramStr,lineStr);
numItems = NumHCItems(lineStr);
if (numItems != 3) {
strcpy(paramStr,"Not enough parameters in sort specification line: ");
NumToString((long)i+1,lineStr);
PtoCstr((char*)lineStr);
strcat(paramStr,lineStr);
ResultIs(paramPtr,paramStr);
RestoreA4();
return;
}
for (j=0;j<3;j++) {
GetHCItem(lineStr,j+1,itemStr);
switch (j) {
case 0:
if (ValidStrToNum(itemStr,&sortItem[i])!=TRUE) {
strcpy(paramStr,"Sort item must be a number in line: ");
NumToString((long)j+1,lineStr);
PtoCstr((char*)lineStr);
strcat(paramStr,lineStr);
ResultIs(paramPtr,paramStr);
RestoreA4();
return;
}
break;
case 1:
ucase(itemStr);
if (strcmp(itemStr,"NUMERIC")==0) sortType[i] = numeric;
else if (strcmp(itemStr,"DATE")==0) sortType[i] = date;
else if (strcmp(itemStr,"TIME")==0) sortType[i] = time;
else sortType[i] = alpha; /* default */
break;
case 2:
ucase(itemStr);
c = itemStr[0];
switch (c) {
case 'A': sortDirection[i] = ascend;break;
case 'D': sortDirection[i] = descend;break;
default: sortDirection[i] = ascend;break;
}
break;
}
}
}
/* do the sort */
paramPtr->returnValue = DoSort(numSortFields);
/* clean up */
HUnlock (paramPtr->params[0]);
HUnlock (paramPtr->params[1]);
RestoreA4();
return;
}
-- part contents for card part 9
----- text -----
MultiSort version 1.0d4
Roger Brown
This is a HyperCard XFCN that sorts the lines of a HyperCard container according to the value of specified items in the line. It will do a multilevel sort on several items and can sort ascending or descending
by alphabetic, numeric, time, or date order.
There is no limit to the number of lines except for available memory. It uses the Lightspeed C quicksort function and it is quite fast! Only one pass is made over the data to find line starts.
Case is ignored in this version.
Syntax is:
get MultiSort(container,specification)
where container is any hypercard container
(field, variable), presumed to be
multi-lined.
specification is a container with this
format:
for each item to sort on, in priority
order, specify one line of three
items: item number to sort on,
sort type (alpha,numeric,date,time),
and ascending or descending (a,d)
returns: a copy of the container sorted by
line or error messages.
ex. get MultiSort(card field 1,spec)
where spec is:
2,alpha,a (item 2, alphabetic order,
ascending)
3,numeric,d (then item 3, numeric,
descending)
Note on data formats:
Time items must be in format hh:mm:ss (ex.
10:15:02). Seconds and hours are optional.
MultiSort WILL NOT report improperly
formatted times and WILL NOT correct for mis-
specified time (ex. 9:99 the way that
HyperCard can. If you are uncertain of time
data, convert it to seconds in HyperTalk and
sort it numerically.
Date items must be in format mm/dd/yy
(ex. 2/15/78). All three parts must be
specified. MultiSort WILL NOT report
improperly formatted dates and WILL NOT
correct for mis-specified dates (ex. 1/44/50)
the way that HyperCard can. If you are
uncertain of date data, convert it to seconds
in HyperTalk and sort it numerically.
REVISION HISTORY
1.0d3 First public release.
1.0d4 uses international string comparison for alpha